using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Reflection;
using LeisureCenter.Api;
using LeisureCenter.Forms;

namespace LeisureCenter.Core
{
    public class PluginsManager
    {
        Dictionary<string, IPlugin> plugins = new Dictionary<string, IPlugin>();

        private void LoadPlugin(string fileName)
        {
            Assembly pluginAssembly = Assembly.LoadFrom(fileName);
            foreach (Type pluginType in pluginAssembly.GetTypes())
            {
                Type pluginInterface = pluginType.GetInterface("LeisureCenter.Api.IPlugin", true);
                if (pluginInterface != null)
                {
                    IPlugin plugin = (IPlugin)Activator.CreateInstance(pluginAssembly.GetType(pluginType.ToString()));
                    plugin.Initialize(Program.LeisureCenterInstance);
                    plugins.Add(fileName, plugin);
                    return;
                }
            }
        }

        #if DEBUG
        private void LoadPluginsFromDebugDirectories(LoadingForm loadingForm)
        {
            DirectoryInfo pluginsRootPath = new DirectoryInfo(Path.GetDirectoryName(Application.ExecutablePath) + @"\..\..\..\Plugins");
            foreach (FileSystemInfo fileSystemInfo in pluginsRootPath.GetFileSystemInfos())
            {
                if (fileSystemInfo is DirectoryInfo && ((fileSystemInfo.Attributes & FileAttributes.Hidden) == 0))
                {
                    FileInfo fileInfo = new FileInfo(fileSystemInfo.FullName + @"\bin\Debug\" + fileSystemInfo.Name + @".dll");
                    if (fileInfo.Exists)
                    {
                        loadingForm.VerboseWithStep(String.Format(@"Loading {0} plugin...", Path.GetFileNameWithoutExtension(fileInfo.Name)));
                        LoadPlugin(fileInfo.FullName);
                    }
                }
            }
        }
        #endif

        #if !DEBUG
        private void LoadPluginsFromPluginsDirectory(LoadingForm loadingForm)
        {
            DirectoryInfo pluginsRootPath = new DirectoryInfo(Path.GetDirectoryName(Application.ExecutablePath) + @"\..\plugins");
            foreach (FileSystemInfo fileSystemInfo in pluginsRootPath.GetFileSystemInfos())
            {
                if (fileSystemInfo is FileInfo && (fileSystemInfo.Extension.Equals(@".dll", StringComparison.InvariantCultureIgnoreCase)))
                {
                    FileInfo fileInfo = (FileInfo)(fileSystemInfo);
                    if (fileInfo.Exists)
                    {
                        loadingForm.VerboseWithStep(String.Format(@"Loading {0} plugin...", Path.GetFileNameWithoutExtension(fileInfo.Name)));
                        LoadPlugin(fileInfo.FullName);
                    }
                }
            }
        }
        #endif

        public void LoadPlugins(LoadingForm loadingForm)
        {
            #if DEBUG
            LoadPluginsFromDebugDirectories(loadingForm);
            #else
            LoadPluginsFromPluginsDirectory(loadingForm);
            #endif
        }

        public void UnloadPlugins()
        {
            foreach (IPlugin plugin in plugins.Values)
            {
                plugin.Finalize(Program.LeisureCenterInstance);
            }
        }
    }
}
